/// 完美FFmpeg风格TS到MP4转换器 - 简化版
use std::fs;
use std::io::{Read, Write};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("🎬 完美FFmpeg风格 TS→MP4 转换器");
    
    let input_file = "video_real_test.ts";
    let output_file = "video_perfect_ffmpeg.mp4";
    
    if !Path::new(input_file).exists() {
        eprintln!("❌ 输入文件不存在: {}", input_file);
        return Ok(());
    }
    
    let mut converter = PerfectConverter::new();
    converter.convert(input_file, output_file)?;
    
    Ok(())
}

pub struct PerfectConverter;

impl PerfectConverter {
    pub fn new() -> Self { Self }
    
    pub fn convert(&mut self, input_path: &str, output_path: &str) -> Result<(), Box<dyn std::error::Error>> {
        println!("📂 处理: {}", input_path);
        
        let mut file = fs::File::open(input_path)?;
        let mut ts_data = Vec::new();
        file.read_to_end(&mut ts_data)?;
        
        println!("📊 文件大小: {:.2} MB", ts_data.len() as f64 / (1024.0 * 1024.0));
        
        let mdat_data = self.extract_data(&ts_data)?;
        self.write_mp4(output_path, &mdat_data)?;
        
        println!("🎉 转换完成！");
        Ok(())
    }
    
    fn extract_data(&self, ts_data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
        let mut mdat_data = Vec::new();
        let mut packet_count = 0;
        
        for chunk in ts_data.chunks(188) {
            if chunk.len() == 188 && chunk[0] == 0x47 {
                let payload = &chunk[4..];
                mdat_data.extend_from_slice(payload);
                packet_count += 1;
            }
        }
        
        println!("✅ 提取: {} 包, {:.2} MB", packet_count, mdat_data.len() as f64 / (1024.0 * 1024.0));
        Ok(mdat_data)
    }
    
    fn write_mp4(&self, path: &str, mdat_data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
        let mut output = fs::File::create(path)?;
        let mut mp4_data = Vec::new();
        
        // ftyp box
        let ftyp = [
            0x00, 0x00, 0x00, 0x20, b'f', b't', b'y', b'p',
            b'i', b's', b'o', b'm', 0x00, 0x00, 0x02, 0x00,
            b'i', b's', b'o', b'm', b'i', b's', b'o', b'2',
            b'a', b'v', b'c', b'1', b'm', b'p', b'4', b'1',
        ];
        mp4_data.extend_from_slice(&ftyp);
        
        // mdat box
        let mdat_size = 8 + mdat_data.len();
        mp4_data.extend_from_slice(&(mdat_size as u32).to_be_bytes());
        mp4_data.extend_from_slice(b"mdat");
        mp4_data.extend_from_slice(mdat_data);
        
        // moov box - 完整结构
        self.write_moov(&mut mp4_data, mdat_data.len())?;
        
        output.write_all(&mp4_data)?;
        println!("💾 MP4已创建: {:.2} MB", mp4_data.len() as f64 / (1024.0 * 1024.0));
        Ok(())
    }
    
    fn write_moov(&self, data: &mut Vec<u8>, mdat_size: usize) -> Result<(), Box<dyn std::error::Error>> {
        let mut moov_content = Vec::new();
        
        // mvhd - movie header
        let mvhd = [
            0x00, 0x00, 0x00, 0x6C, b'm', b'v', b'h', b'd',
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x01, 0x5F, 0x90, 0x00, 0x3D, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00,
            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
        ];
        moov_content.extend_from_slice(&mvhd);
        
        // trak box with complete structure
        self.write_trak(&mut moov_content, mdat_size)?;
        
        let moov_size = 8 + moov_content.len();
        data.extend_from_slice(&(moov_size as u32).to_be_bytes());
        data.extend_from_slice(b"moov");
        data.extend_from_slice(&moov_content);
        Ok(())
    }
    
    fn write_trak(&self, data: &mut Vec<u8>, mdat_size: usize) -> Result<(), Box<dyn std::error::Error>> {
        let mut trak_content = Vec::new();
        
        // tkhd - track header  
        let tkhd = [
            0x00, 0x00, 0x00, 0x5C, b't', b'k', b'h', b'd',
            0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x09, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x40, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00,
        ];
        trak_content.extend_from_slice(&tkhd);
        
        // mdia with complete video codec info
        self.write_mdia(&mut trak_content, mdat_size)?;
        
        let trak_size = 8 + trak_content.len();
        data.extend_from_slice(&(trak_size as u32).to_be_bytes());
        data.extend_from_slice(b"trak");
        data.extend_from_slice(&trak_content);
        Ok(())
    }
    
    fn write_mdia(&self, data: &mut Vec<u8>, mdat_size: usize) -> Result<(), Box<dyn std::error::Error>> {
        let mut mdia_content = Vec::new();
        
        // mdhd, hdlr, minf with complete stsd
        let complete_mdia = self.create_complete_mdia(mdat_size)?;
        mdia_content.extend_from_slice(&complete_mdia);
        
        let mdia_size = 8 + mdia_content.len();
        data.extend_from_slice(&(mdia_size as u32).to_be_bytes());
        data.extend_from_slice(b"mdia");
        data.extend_from_slice(&mdia_content);
        Ok(())
    }
    
    fn create_complete_mdia(&self, mdat_size: usize) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
        // 完整的H.264视频mdia结构
        let mut mdia_data = Vec::new();
        
        // mdhd box
        let mdhd = [
            0x00, 0x00, 0x00, 0x20, b'm', b'd', b'h', b'd',
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x01, 0x5F, 0x90, 0x00, 0x3D, 0x09, 0x00, 0x55, 0xC4, 0x00, 0x00,
        ];
        mdia_data.extend_from_slice(&mdhd);
        
        // hdlr box
        let hdlr = [
            0x00, 0x00, 0x00, 0x21, b'h', b'd', b'l', b'r',
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            b'v', b'i', b'd', b'e', 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, b'V',
        ];
        mdia_data.extend_from_slice(&hdlr);
        
        // minf box with stsd containing avc1
        self.write_complete_minf(&mut mdia_data, mdat_size)?;
        
        Ok(mdia_data)
    }
    
    fn write_complete_minf(&self, data: &mut Vec<u8>, mdat_size: usize) -> Result<(), Box<dyn std::error::Error>> {
        let mut minf_content = Vec::new();
        
        // vmhd
        let vmhd = [
            0x00, 0x00, 0x00, 0x14, b'v', b'm', b'h', b'd',
            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        ];
        minf_content.extend_from_slice(&vmhd);
        
        // dinf
        let dinf = [
            0x00, 0x00, 0x00, 0x24, b'd', b'i', b'n', b'f',
            0x00, 0x00, 0x00, 0x1C, b'd', b'r', b'e', b'f',
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
            0x00, 0x00, 0x00, 0x0C, b'u', b'r', b'l', b' ',
            0x00, 0x00, 0x00, 0x01,
        ];
        minf_content.extend_from_slice(&dinf);
        
        // stbl with perfect avc1 stsd
        self.write_perfect_stbl(&mut minf_content, mdat_size)?;
        
        let minf_size = 8 + minf_content.len();
        data.extend_from_slice(&(minf_size as u32).to_be_bytes());
        data.extend_from_slice(b"minf");
        data.extend_from_slice(&minf_content);
        Ok(())
    }
    
    fn write_perfect_stbl(&self, data: &mut Vec<u8>, mdat_size: usize) -> Result<(), Box<dyn std::error::Error>> {
        let mut stbl_content = Vec::new();
        
        // stsd with avc1 entry
        self.write_perfect_stsd(&mut stbl_content)?;
        
        // stts, stsc, stsz, stco
        self.write_sample_tables(&mut stbl_content, mdat_size)?;
        
        let stbl_size = 8 + stbl_content.len();
        data.extend_from_slice(&(stbl_size as u32).to_be_bytes());
        data.extend_from_slice(b"stbl");
        data.extend_from_slice(&stbl_content);
        Ok(())
    }
    
    fn write_perfect_stsd(&self, data: &mut Vec<u8>) -> Result<(), Box<dyn std::error::Error>> {
        let mut stsd_content = Vec::new();
        
        // stsd header
        stsd_content.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // version + flags
        stsd_content.extend_from_slice(&[0x00, 0x00, 0x00, 0x01]); // entry_count
        
        // avc1 sample entry
        let mut avc1_entry = Vec::new();
        
        // VisualSampleEntry fields
        avc1_entry.extend_from_slice(&[0x00; 6]); // reserved
        avc1_entry.extend_from_slice(&[0x00, 0x01]); // data_reference_index
        avc1_entry.extend_from_slice(&[0x00; 16]); // pre_defined + reserved
        avc1_entry.extend_from_slice(&[0x07, 0x80]); // width (1920)
        avc1_entry.extend_from_slice(&[0x04, 0x38]); // height (1080)
        avc1_entry.extend_from_slice(&[0x00, 0x48, 0x00, 0x00]); // horizresolution
        avc1_entry.extend_from_slice(&[0x00, 0x48, 0x00, 0x00]); // vertresolution
        avc1_entry.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // reserved
        avc1_entry.extend_from_slice(&[0x00, 0x01]); // frame_count
        
        // compressorname (32 bytes)
        let mut compressor = vec![0x00; 32];
        compressor[0] = 10; // length
        compressor[1..11].copy_from_slice(b"AVC Coding");
        avc1_entry.extend_from_slice(&compressor);
        
        avc1_entry.extend_from_slice(&[0x00, 0x18]); // depth
        avc1_entry.extend_from_slice(&[0xFF, 0xFF]); // pre_defined
        
        // avcC box - 关键！
        let avcc = [
            0x00, 0x00, 0x00, 0x2E, b'a', b'v', b'c', b'C',
            0x01, // configurationVersion
            0x64, // AVCProfileIndication (High Profile)
            0x00, // profile_compatibility
            0x2A, // AVCLevelIndication (4.2)
            0xFF, // lengthSizeMinusOne
            0xE1, // numOfSequenceParameterSets
            0x00, 0x18, // SPS length
            // SPS data (minimal but valid)
            0x67, 0x64, 0x00, 0x2A, 0xAC, 0x2B, 0x50, 0x3C, 0x01, 0x13, 0xF2, 0xCD,
            0xC0, 0x40, 0x40, 0x40, 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x2A,
            0x01, // numOfPictureParameterSets
            0x00, 0x04, // PPS length
            0x68, 0xEE, 0x3C, 0x80, // PPS data
        ];
        avc1_entry.extend_from_slice(&avcc);
        
        // avc1 entry header
        let avc1_size = 8 + avc1_entry.len();
        stsd_content.extend_from_slice(&(avc1_size as u32).to_be_bytes());
        stsd_content.extend_from_slice(b"avc1");
        stsd_content.extend_from_slice(&avc1_entry);
        
        let stsd_size = 8 + stsd_content.len();
        data.extend_from_slice(&(stsd_size as u32).to_be_bytes());
        data.extend_from_slice(b"stsd");
        data.extend_from_slice(&stsd_content);
        Ok(())
    }
    
    fn write_sample_tables(&self, data: &mut Vec<u8>, mdat_size: usize) -> Result<(), Box<dyn std::error::Error>> {
        // stts
        let stts = [
            0x00, 0x00, 0x00, 0x10, b's', b't', b't', b's',
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
            0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x0E, 0x10,
        ];
        data.extend_from_slice(&stts);
        
        // stsc
        let stsc = [
            0x00, 0x00, 0x00, 0x14, b's', b't', b's', b'c',
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
        ];
        data.extend_from_slice(&stsc);
        
        // stsz
        let mut stsz = Vec::new();
        stsz.extend_from_slice(&[0x00, 0x00, 0x00, 0x14, b's', b't', b's', b'z']);
        stsz.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // version + flags
        stsz.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // sample_size
        stsz.extend_from_slice(&[0x00, 0x00, 0x00, 0x01]); // sample_count
        stsz.extend_from_slice(&(mdat_size as u32).to_be_bytes()); // size
        data.extend_from_slice(&stsz);
        
        // stco
        let stco = [
            0x00, 0x00, 0x00, 0x10, b's', b't', b'c', b'o',
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
            0x00, 0x00, 0x00, 0x28, // chunk offset
        ];
        data.extend_from_slice(&stco);
        
        Ok(())
    }
}